
#ifndef __SRC_TASK_DISPATCHER_IMPL_H__
#define __SRC_TASK_DISPATCHER_IMPL_H__

#include <atomic>
#include <condition_variable>
#include <list>
#include <memory>
#include <thread>

#include "task_dispatcher.h"

namespace dispatcher
{

class DispatcherStateManager;

class TaskDispatcherImpl
{
public:
    using TaskSptr         = std::shared_ptr<Task>;
    using Mutex            = std::mutex;
    using UniqueLocker     = std::unique_lock<Mutex>;
    using StateManagerSPtr = std::shared_ptr<DispatcherStateManager>;

public:
    TaskDispatcherImpl();
    ~TaskDispatcherImpl();

    bool AddTaskImpl(TaskSptr task, Task::TaskType type);

private:
    void DispatcherThread();

private:
    std::list<TaskSptr> tasks_;
    StateManagerSPtr    state_manager_sptr_;
    std::thread         dispatcher_thread_;

    Mutex                   new_task_lock_;
    std::condition_variable task_add_condition_;

    Mutex                   finished_task_lock_;
    std::condition_variable task_finished_condition_;
};

}  // namespace dispatcher

#endif  // __SRC_TASK_DISPATCHER_IMPL_H__
